package com.myGis.services;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.hibernate.Session;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;

import com.myGis.entities.Layer;
import com.myGis.entities.SimpleField;
import com.myGis.entities.SpatialObject;
import com.myGis.entities.ValueField;
import com.myGis.persistence.IPersistenceData;
import com.myGis.persistence.PersistenceData;
import com.vividsolutions.jts.geom.GeometryCollection;

public class FileLayerShapeManager extends FileLayerManager implements IFileLayerManager{

	public FileLayerShapeManager(Session session) {
		super(session);
	}
	
	@Override
	public Layer execute(File file, Layer layer) throws Exception {

		URL url = null;
        ShapefileDataStore ds;
		url = file.toURL();
		ds = new ShapefileDataStore(url);
    	String name = ds.getTypeNames()[0];
    	SimpleFeatureSource source;
		source = ds.getFeatureSource(name);
		//source.getInfo().getCRS().getCoordinateSystem();
    	SimpleFeatureCollection featureCollection= source.getFeatures();
    	SimpleFeatureIterator itFeatureCollection = featureCollection.features();
    	SimpleFeatureIterator itFeature = featureCollection.features();
    	
    	List<SimpleField> nameColumn = 	createSimpleField(itFeature.next(),layer);
    	//Agrego los simpleField a Layer
    	layer.getSimpleFields().addAll(nameColumn);
    	
    	int i = 0;
    	while (itFeatureCollection.hasNext()){
    		SimpleFeature simpleFeature = (SimpleFeature)itFeatureCollection.next();
    		SpatialObject so = createSpatialObject(simpleFeature,layer);
    		//Agrego el Spatial Object al layer
    		layer.getSpatialObject().add(so);
    		Iterator<Property> itProperty = simpleFeature.getProperties().iterator();
    		int j = 0 ;
    		while (itProperty.hasNext()) {
    			Property property = (Property) itProperty.next();
    			if(!util.isGeometry(property.getType().getName().toString())){
    				ValueField vf= createValueField(nameColumn.get(j), so,property);
    				//Agrego el value field al Spatial Object y al Simple Field 
    				so.getValueFields().add(vf);
    				nameColumn.get(j).getValueFields().add(vf);
        			j++;
    			}
			}
    		i++;
    	}
		return layer;
		
		
	}
	
	private ValueField createValueField(SimpleField sf, SpatialObject so, Property property) {
		ValueField vf = new ValueField();
		vf.setSimpleField(sf);
		vf.setSpatialObject(so);
		vf.setValue(property.getValue().toString());
		IPersistenceData persistenceData = new PersistenceData(this.session); 
		persistenceData.save(vf);
		return vf;
	}

	private List<SimpleField> createSimpleField(SimpleFeature simpleFeature, Layer layer) {
		List<SimpleField> simpleField = new ArrayList<SimpleField>();
		Iterator<Property> itProperty = simpleFeature.getProperties().iterator();

		while (itProperty.hasNext()) {
			Property property = (Property) itProperty.next();
			if(!util.isGeometry(property.getType().getName().toString())){
				IPersistenceData persistenceData = new PersistenceData(this.session); 
				SimpleField sf = new SimpleField();
				sf.setName(property.getName().toString());
				sf.setType(property.getType().getBinding().toString());
				sf.setLayer(layer);
				persistenceData.save(sf);
				simpleField.add(sf);
			}
		}
    	return simpleField;
	}
	
	
	private SpatialObject createSpatialObject(SimpleFeature simpleFeature, Layer layer) {
		Iterator<Property> itProperty = simpleFeature.getProperties().iterator();
		SpatialObject so = new SpatialObject();
		while (itProperty.hasNext()) {
			Property property = (Property) itProperty.next();
			
			if(util.isGeometry(property.getType().getName().toString())){
				IPersistenceData persistenceData = new PersistenceData(this.session); 
				so.setLayer(layer);
 				GeometryCollection gc = (GeometryCollection) property.getValue();
 				//TODO Tenemos problemas cuando se va a insertar el objeto espacil ya que no tenemos definido el SRID.
				gc.setSRID(22195);
				so.setGeometry(gc);
				persistenceData.save(so);
			}
		}
    	return so;
	}
	
}
